package com.lixueju.security.box.web.weixin.model;

import com.alibaba.fastjson.JSON;
import com.lixueju.security.box.core.exception.SecurityBoxException;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.nio.charset.StandardCharsets;
import java.security.InvalidAlgorithmParameterException;

/**
 * @author lixueju
 * @since 2019/10/10 17:04
 **/
public class WeixinBizDataCrypt {
    final Logger logger = LoggerFactory.getLogger(getClass());

    private String appid;

    private String sessionKey;

    public WeixinBizDataCrypt(String appid, String sessionKey) {
        this.appid = appid;
        this.sessionKey = sessionKey;
    }

    public WeixinUserInfo decryptDataForUserInfo(String encryptedData, String iv) {
        return JSON.parseObject(decryptData(encryptedData,iv), WeixinUserInfo.class);
    }

    public WeixinPhoneNumber decryptDataForPhoneNumber(String encryptedData, String iv) {
        return JSON.parseObject(decryptData(encryptedData,iv), WeixinPhoneNumber.class);
    }

    /**
     * 检验数据的真实性，并且获取解密后的明文.
     *
     * @param encryptedData string 加密的用户数据
     * @param iv            string 与用户数据一同返回的初始向量
     * @return data string 解密后的原文
     */
    public String decryptData(String encryptedData, String iv) {
        logger.info("sessionKey.length===" + StringUtils.length(sessionKey));
        if (StringUtils.length(sessionKey) != 24) {
            throw new SecurityBoxException("ErrorCode::$IllegalAesKey;");
        }
        logger.info("sessionKey:" + sessionKey);
        logger.info("encryptedData:" + encryptedData);
        logger.info("iv:" + iv);
        // 对称解密秘钥 aeskey = Base64_Decode(session_key), aeskey 是16字节。
        byte[] aesKey = Base64.decodeBase64(sessionKey);
        logger.info("iv.length===" + StringUtils.length(iv));
        if (StringUtils.length(iv) != 24) {
            throw new SecurityBoxException("ErrorCode::$IllegalIv;");
        }
        // 对称解密算法初始向量 为Base64_Decode(iv)，其中iv由数据接口返回。
        byte[] aesIV = Base64.decodeBase64(iv);
        // 对称解密的目标密文为 Base64_Decode(encryptedData)
        byte[] aesCipher = Base64.decodeBase64(encryptedData);
        try {
            //AESUtil解密
            byte[] resultByte = AESUtil.decrypt(aesCipher, aesKey, aesIV);

            if (null != resultByte && resultByte.length > 0) {
                return new String(resultByte, StandardCharsets.UTF_8);
            } else {
                throw new SecurityBoxException("AESUtil解密失败");
            }
        } catch (InvalidAlgorithmParameterException e) {
            e.printStackTrace();
        }
        throw new SecurityBoxException("AESUtil解密失败");
    }
}
